package org.hncors.gnssparse;
import android.Manifest;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Build;
import android.os.Handler;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.RadioGroup;
import android.widget.TextView;
import android.widget.Toast;

import com.baidu.location.BDAbstractLocationListener;
import com.baidu.location.BDLocation;
import com.baidu.location.BDLocationListener;
import com.baidu.location.LocationClient;
import com.baidu.location.LocationClientOption;
import com.baidu.mapapi.CoordType;
import com.baidu.mapapi.SDKInitializer;
import com.baidu.mapapi.map.BaiduMap;
import com.baidu.mapapi.map.BitmapDescriptor;
import com.baidu.mapapi.map.BitmapDescriptorFactory;
import com.baidu.mapapi.map.MapStatus;
import com.baidu.mapapi.map.MapStatusUpdateFactory;
import com.baidu.mapapi.map.MapView;
import com.baidu.mapapi.map.Marker;
import com.baidu.mapapi.map.MarkerOptions;
import com.baidu.mapapi.map.MyLocationConfiguration;
import com.baidu.mapapi.map.MyLocationData;
import com.baidu.mapapi.map.OverlayOptions;
import com.baidu.mapapi.model.LatLng;
import com.baidu.mapapi.utils.CoordinateConverter;
import com.southgnss.connect.DeviceParManage;
import com.southgnss.connect.GnssInfoCallBackLinstner;
import com.southgnss.connect.TopDeviceManage;
import com.southgnss.location.DateUtil;

import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;


public class MapActivity extends AppCompatActivity implements View.OnClickListener, GnssInfoCallBackLinstner, SensorEventListener {
   // 定位相关
    LocationClient mLocClient;
    public MyLocationListener myListener = new MyLocationListener();
    private MyLocationConfiguration.LocationMode mCurrentMode;
    BitmapDescriptor mCurrentMarker;
    private static final int accuracyCircleFillColor = 0xAAFFFF88;
    private static final int accuracyCircleStrokeColor = 0xAA00FF00;
    private SensorManager mSensorManager;
    private Double lastX = 0.0;
    private int mCurrentDirection = 0;
    private double mCurrentLat = 0.0;
    private double mCurrentLon = 0.0;
    private float mCurrentAccracy;

    MapView mMapView;
    BaiduMap mBaiduMap;

    // UI相关
    RadioGroup.OnCheckedChangeListener radioButtonListener;
    Button requestLocButton;
    boolean isFirstLoc = true; // 是否首次定位
    private MyLocationData locData;
    private float direction;

    private Button mapTypeButton;


    private TextView nameTv;

    private TextView bValueTv;

    private TextView lValueTv;

    private TextView hValueTv;

    private TextView timeTv;

    private TextView precisionTv;

    private TextView speedTv;

    private boolean isGranter = false;
    private final int REQUEST_PHONE_PERMISSIONS = 0;

    private Marker gnssMarker;
    static Handler mHandler = new Handler();
    Runnable onTimerRunnable = new Runnable() {
        @Override
        public void run() {
//            String strInfo = String.format(Locale.ENGLISH, "%s:%.10f%n %s:%.10f%n %s:%.4f%n %s:%.4f%n %s:%.4f%n " +
//                            "%s:%.4f%n %s:%.4f%n %s:%.4f%n %s:%.4f%n %s:%.4f%n %s:%s%n %s:%s%n %s:%d%n %s:%d%n " +
//                            "%s:%s%n %s:%s%n %s:%s%n %s:%s%n "
//
//                    , getString(R.string.B), TopDeviceManage.getInstance(null).getLatitude()
//                    , getString(R.string.L), TopDeviceManage.getInstance(null).getLongitude()
//                    , getString(R.string.H), TopDeviceManage.getInstance(null).getAltitude()
//                    , getString(R.string.HRMS), TopDeviceManage.getInstance(null).getHrms()
//                    , getString(R.string.speed), TopDeviceManage.getInstance(null).getSpeed()
//                    , getString(R.string.heading), TopDeviceManage.getInstance(null).getBearing()
//                    , getString(R.string.PDOP), TopDeviceManage.getInstance(null).getPdop()
//                    , getString(R.string.HDOP), TopDeviceManage.getInstance(null).getHdop()
//                    , getString(R.string.VDOP), TopDeviceManage.getInstance(null).getVdop()
//                    , getString(R.string.VRMS), TopDeviceManage.getInstance(null).getVrms()
//                    , getString(R.string.statusType), getCurSolutionState(TopDeviceManage.getInstance(null).getStatusType())
//                    , getString(R.string.time), DateUtil.formatDate(new Date(TopDeviceManage.getInstance(null).getLocalTime()))
//                    , getString(R.string.age), TopDeviceManage.getInstance(null).getAge()
//                    , getString(R.string.m_tSatNum), TopDeviceManage.getInstance(null).getSatInView()
//                    , "固件版本", DeviceParManage.GetInstance().GetRTKAppVer()
//                    , "工作模式", DeviceParManage.GetInstance().GetCurSysMode()
//                    , "电池剩余", DeviceParManage.GetInstance().getPowerFree().isEmpty() ? "" : (DeviceParManage.GetInstance().getPowerFree() + "%")
//                    , "差分站ID", TopDeviceManage.getInstance(null).getChangeStationID()
//            );
            // tvGnssInfo.setText(strInfo);
            try {
                refreshUI();
            } catch (Exception ex) {
                ex.printStackTrace();
            }
            mHandler.postDelayed(onTimerRunnable, 1000);
        }
    };
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        SDKInitializer.initialize(getApplicationContext());
        SDKInitializer.setCoordType(CoordType.GCJ02);
        setContentView(R.layout.activity_map);
        checkPermission();
        initData();
        initView();
        initMap();
    }
    private void initData() {
        TopDeviceManage.getInstance(this).setGnssInfoListener(this);
    }
    private void initView() {
        mMapView = (MapView) findViewById(R.id.mmap);
        mapTypeButton = (Button) findViewById(R.id.map_type_button);
        nameTv = (TextView) findViewById(R.id.name_tv);
        bValueTv = (TextView) findViewById(R.id.b_value_tv);
        lValueTv = (TextView) findViewById(R.id.l_value_tv);
        hValueTv = (TextView) findViewById(R.id.h_value_tv);
        timeTv = (TextView) findViewById(R.id.time_tv);
        precisionTv = (TextView) findViewById(R.id.precision_tv);
        speedTv = (TextView) findViewById(R.id.speed_tv);

        mBaiduMap = mMapView.getMap();
        mHandler.post(onTimerRunnable);

        mapTypeButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (mapTypeButton.isSelected()) {
                    mBaiduMap.setMapType(BaiduMap.MAP_TYPE_NORMAL);
                } else {
                    mBaiduMap.setMapType(BaiduMap.MAP_TYPE_SATELLITE);
                }
                mapTypeButton.setSelected(!mapTypeButton.isSelected());
            }
        });
    }
    private void initMap() {
        mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);//获取传感器管理服务
        mCurrentMode = MyLocationConfiguration.LocationMode.FOLLOWING;
        // 开启定位图层
        mBaiduMap.setMyLocationEnabled(true);

        // 定位初始化
        mLocClient = new LocationClient(getApplicationContext());
        mLocClient.registerLocationListener(myListener);
        LocationClientOption option = new LocationClientOption();
        option.setLocationMode(LocationClientOption.LocationMode.Hight_Accuracy);
        option.setOpenGps(true); // 打开gps
        option.setCoorType("bd09ll"); // 设置坐标类型
        option.setScanSpan(1000);
        mLocClient.setLocOption(option);
        mLocClient.start();
        mLocClient.requestLocation();
    }
    @Override
    protected void onPause() {
        mMapView.onPause();
        super.onPause();
    }

    @Override
    protected void onResume() {
        mMapView.onResume();
        super.onResume();
        //为系统的方向传感器注册监听器
        mSensorManager.registerListener(this, mSensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION),
                SensorManager.SENSOR_DELAY_UI);
    }

    @Override
    protected void onStop() {
        //取消注册传感器监听
        mSensorManager.unregisterListener(this);
        super.onStop();
    }

    @Override
    protected void onDestroy() {
        // 退出时销毁定位
        mLocClient.stop();
        // 关闭定位图层
        mBaiduMap.setMyLocationEnabled(false);
        mMapView.onDestroy();
        mMapView = null;
        super.onDestroy();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.menu_main, menu);
        return super.onCreateOptionsMenu(menu);
    }
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch(item.getItemId()) {
            case android.R.id.home:
                super.onBackPressed();
                return true;
            case R.id.setting:
            {
//                Intent intent = new Intent(this, MainActivity.class);
//                startActivity(intent);
                finish();
                return true;
            }
            case R.id.gnss_plot:
            {
                Intent intent = new Intent(this, SatellitesViewActivity.class);
                startActivity(intent);
                return true;
            }
        }
        return super.onOptionsItemSelected(item);
    }



    private void refreshUI() {
        DecimalFormat nf = new DecimalFormat("#0.0000");
        DecimalFormat speedDf = new DecimalFormat("#0.00");
        TopDeviceManage topDeviceManage = TopDeviceManage.getInstance(null);
        nameTv.setText(ProgramConfigWrapper.GetInstance(this).GetBluetoothName());
        bValueTv.setText(nf.format(topDeviceManage.getLatitude()));
        lValueTv.setText(nf.format(topDeviceManage.getLongitude()));
        hValueTv.setText(nf.format(topDeviceManage.getAltitude()));
        timeTv.setText(DateUtil.formatDate(new Date(topDeviceManage.getLocalTime()), "HH:mm:ss"));
        precisionTv.setText(nf.format(topDeviceManage.getPdop()));
        speedTv.setText(speedDf.format(topDeviceManage.getSpeed()));
        refreshMarker(topDeviceManage.getLatitude(), topDeviceManage.getLongitude());
    }
    private void refreshMarker(Double lat, Double lng) {
        if (lat > 0 && lng > 0) {
            LatLng sourceLatLng = new LatLng(lat, lng);
            CoordinateConverter converter  = new CoordinateConverter();
            converter.from(CoordinateConverter.CoordType.GPS);

// sourceLatLng待转换坐标

            converter.coord(sourceLatLng);
            LatLng point = converter.convert();
            //构建Marker图标

            if (gnssMarker == null) {
                BitmapDescriptor bitmap = BitmapDescriptorFactory
                        .fromResource(R.drawable.icon_gcoding);
                OverlayOptions option = new MarkerOptions()
                        .icon(bitmap)
                        .position(point);
                mBaiduMap.addOverlay(option);
            } else {
                gnssMarker.setPosition(point);
            }
            MapStatus.Builder builder = new MapStatus.Builder();
            builder.target(point).zoom(16.0f);
            mBaiduMap.animateMapStatus(MapStatusUpdateFactory.newMapStatus(builder.build()));
        }
    }

    @Override
    public void onClick(View v) {

    }

    @Override
    public void callback(String s) {

    }

    @Override
    public void connectCallback(boolean b) {

    }

    @Override
    public void onSensorChanged(SensorEvent sensorEvent) {
        double x = sensorEvent.values[SensorManager.DATA_X];
        if (Math.abs(x - lastX) > 1.0) {
            mCurrentDirection = (int) x;
            locData = new MyLocationData.Builder()
                    .accuracy(mCurrentAccracy)
                    // 此处设置开发者获取到的方向信息，顺时针0-360
                    .direction(mCurrentDirection).latitude(mCurrentLat)
                    .longitude(mCurrentLon).build();
            mBaiduMap.setMyLocationData(locData);
        }
        lastX = x;
    }

    @Override
    public void onAccuracyChanged(Sensor sensor, int i) {

    }

    /**
     * 定位SDK监听函数
     */
//    public class MyLocationListenner implements BDAbstractLocationListener {
//
//        @Override
//        public void onReceiveLocation(BDLocation location) {
//            // map view 销毁后不在处理新接收的位置
//            if (location == null || mMapView == null) {
//                return;
//            }
//            mCurrentLat = location.getLatitude();
//            mCurrentLon = location.getLongitude();
//            mCurrentAccracy = location.getRadius();
//            locData = new MyLocationData.Builder()
//                    .accuracy(location.getRadius())
//                    // 此处设置开发者获取到的方向信息，顺时针0-360
//                    .direction(mCurrentDirection).latitude(location.getLatitude())
//                    .longitude(location.getLongitude()).build();
//            mBaiduMap.setMyLocationData(locData);
//            if (isFirstLoc) {
//                isFirstLoc = false;
//                LatLng ll = new LatLng(location.getLatitude(),
//                        location.getLongitude());
//                MapStatus.Builder builder = new MapStatus.Builder();
//                builder.target(ll).zoom(16.0f);
//                mBaiduMap.animateMapStatus(MapStatusUpdateFactory.newMapStatus(builder.build()));
//            }
//        }
//
//        public void onReceivePoi(BDLocation poiLocation) {
//        }
//    }
    public class MyLocationListener extends BDAbstractLocationListener {
        @Override
        public void onReceiveLocation(BDLocation location){
            //此处的BDLocation为定位结果信息类，通过它的各种get方法可获取定位相关的全部结果
            //以下只列举部分获取经纬度相关（常用）的结果信息
            //更多结果信息获取说明，请参照类参考中BDLocation类中的说明

//            double latitude = location.getLatitude();    //获取纬度信息
//            double longitude = location.getLongitude();    //获取经度信息
//            float radius = location.getRadius();    //获取定位精度，默认值为0.0f
//
//            String coorType = location.getCoorType();
//            //获取经纬度坐标类型，以LocationClientOption中设置过的坐标类型为准
//
//            int errorCode = location.getLocType();
            //获取定位类型、定位错误返回码，具体信息可参照类参考中BDLocation类中的说明

            mCurrentLat = location.getLatitude();
            mCurrentLon = location.getLongitude();
            mCurrentAccracy = location.getRadius();
            locData = new MyLocationData.Builder()
                    .accuracy(location.getRadius())
                    // 此处设置开发者获取到的方向信息，顺时针0-360
                    .direction(mCurrentDirection).latitude(location.getLatitude())
                    .longitude(location.getLongitude()).build();
            mBaiduMap.setMyLocationData(locData);
            if (isFirstLoc) {
                isFirstLoc = false;
                LatLng ll = new LatLng(location.getLatitude(),
                        location.getLongitude());
                MapStatus.Builder builder = new MapStatus.Builder();
                builder.target(ll).zoom(16.0f);
                mBaiduMap.animateMapStatus(MapStatusUpdateFactory.newMapStatus(builder.build()));
            }
        }
    }
    public void checkPermission() {
        final List<String> permissionsList = new ArrayList<>();
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){
            if ((checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)!= PackageManager.PERMISSION_GRANTED))
                permissionsList.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
            if ((checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE)!= PackageManager.PERMISSION_GRANTED))
                permissionsList.add(Manifest.permission.READ_EXTERNAL_STORAGE);
            if ((checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION )!= PackageManager.PERMISSION_GRANTED))
                permissionsList.add(Manifest.permission.ACCESS_COARSE_LOCATION );
            if ((checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION  )!= PackageManager.PERMISSION_GRANTED))
                permissionsList.add(Manifest.permission.ACCESS_FINE_LOCATION  );
            if (permissionsList.size() == 0){
//                startRecord();
                isGranter = true;
            }else{
                requestPermissions(permissionsList.toArray(new String[permissionsList.size()]),
                        REQUEST_PHONE_PERMISSIONS);
            }
        }else{
//            startRecord();
            isGranter = true;
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        switch (requestCode) {
            case REQUEST_PHONE_PERMISSIONS:
                if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    isGranter = true;
                    mLocClient.restart();
                } else {

                    Toast.makeText(MapActivity.this, "您需要开通权限，并重启应用！", Toast.LENGTH_LONG).show();
                }
                break;
            default:
                super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        }
    }
}